import os
import re
import pandas as pd
import datetime
import numpy as np
from .code_books import CBA, CBC

def extract_string_date(s, reg_exp, fmt):
    m = re.search(reg_exp, s)
    if m:
        date_str = m.group(1)
        return pd.Timestamp(
            datetime.datetime.strptime(date_str, fmt))


def is_date_valid(d):
    if not isinstance(d, datetime.date):
        return False
    elif d.year != 2021:
        return False
    else:
        return True


def priority_date(s):
    if s is None:
        return s
    return extract_string_date(s, '(\d{4}-\d{2}-\d{2}?)', fmt='%Y-%m-%d')


def select_rows(df, **kwargs):
    this_df = df.copy()
    for key, value in kwargs.items():
        if not isinstance(value, list):
            value = [value]
        this_df = this_df.loc[this_df[key].isin(value)]
    return this_df


def is_in(f):
    if callable(f):
        return f
    elif isinstance(f, list):
        return lambda x: x in f
    else:
        return lambda x: x == f


def is_less_than(x):
    return lambda y: y < x


def is_weakly_less_than(x):
    return lambda y: y <= x


def is_greater_than(x):
    return lambda y: y > x


def is_weakly_greater_than(x):
    return lambda y: y >= x


def is_between(a, b, inclusive='both'):
    if inclusive == 'both':
        return lambda y: a <= y <= b
    if inclusive == 'left':
        return lambda y: a <= y < b
    if inclusive == 'right':
        return lambda y: a < y <= b


def filter_data(data, **kwargs):
    this_df = data.copy()
    for key in kwargs.keys():
        full_key = key if key in this_df.columns else CB.__dict__[key]
        this_df = this_df.loc[this_df[full_key].apply(is_in(kwargs[key]))]
    return this_df


def str_to_date(this_date):
    if isinstance(this_date, str):
        this_date = datetime.datetime.strptime(this_date, '%Y-%m-%d')
    return this_date


def to_date_str(this_date):
    if isinstance(this_date, datetime.date):
        this_date = this_date.strftime('%Y-%m-%d')
    return this_date


date_to_str = to_date_str


def cols_by_date(this_date, add_no_medida_var=None, with_calls_data=None):
    _date_str = date_to_str(this_date)
    if add_no_medida_var:
        if with_calls_data:
            return [c.format(_date_str) for c in
                    ['fwdiff_payments_by_{}', 'payments_by_{}',
                    'priority_by_{}', 'action_by_{}', 'action_no_medida_issued_by_{}',
                     'action_no_medida_by_{}', 'total_calls_by_{}']]
        else:
            return [c.format(_date_str) for c in
                    ['fwdiff_payments_by_{}', 'payments_by_{}',
                     'priority_by_{}', 'action_by_{}', 'action_no_medida_issued_by_{}',
                     'action_no_medida_by_{}']]
    else:
        if with_calls_data:
            return [c.format(_date_str) for c in
                    ['fwdiff_payments_by_{}', 'payments_by_{}',
                    'priority_by_{}', 'action_by_{}',
                     'total_calls_by_{}']]
        else:
            return [c.format(_date_str) for c in
                    ['fwdiff_payments_by_{}', 'payments_by_{}',
                    'priority_by_{}', 'action_by_{}']]

list_dates = pd.date_range(start='2021-04-09', end='2021-09-15', freq='W-MON')

str_assignment_dates = ['052321', '060321', '041821', '082921', '071621', '050721', '070921', '062021', '082021', '051621', '042621', '081421', '053021', '050321', '061621', '070621', '080721', '072321', '040721', '062521']

assignment_dates = [datetime.date(2021,
                                  int(datestring[0:2]),
                                  int(datestring[2:4]))
                    for datestring in str_assignment_dates]
assignment_dates.sort()
